home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / appl / napsaterm / keymap.c < prev    next >
C/C++ Source or Header  |  1994-05-14  |  7KB  |  257 lines

  1. RCS_ID_C "$Id: keymap.c,v 3.3 1994/05/14 12:43:33 ppessi Exp $";
  2. /*
  3.  * Keyboard handling routines
  4.  *
  5.  * $Log: keymap.c,v $
  6.  * Revision 3.3  1994/05/14  12:43:33  ppessi
  7.  * Cleaned up the keyboard conversion code,
  8.  * it fully supports CTRL8BIT option now.
  9.  *
  10.  * Revision 3.2  1994/05/12  10:44:49  ppessi
  11.  * Added application keypad handling (original code by R. Knop)
  12.  *
  13.  */
  14.  
  15. #include <string.h>
  16. #include <stdio.h>
  17.  
  18. #include "nifty.h"
  19. #include "amiga.h"
  20. #include "display.h"
  21. #include "wimp.h"
  22. #include "nio.h"
  23. #include "napsaprefs.h"
  24.  
  25. #include <devices/keymap.h>
  26. #include <intuition/intuition.h>
  27.  
  28. struct IOStdReq consolereq = { 0 };
  29. #define ConsoleDevice (consolereq.io_Device)
  30.  
  31. #ifdef USE_PRAGMAS
  32. #include <proto/keymap.h>
  33. #include <clib/console_protos.h>
  34. #include <pragmas/console_pragmas.h>
  35. #endif
  36. #ifdef USE_INLINE
  37. #include <inline/proto.h>
  38. #include <inline/console.h>
  39. #endif
  40. #ifdef USE_CLIB
  41. #include <clib/keymap_protos.h>
  42. #include <clib/console_protos.h>
  43. #endif
  44.  
  45. struct KeyMap *default_map = NULL; /* used in `international' mode */
  46. struct KeyMap *used_map = NULL;       /* used in multinational/national mode */
  47.  
  48. char keyMapDir[] = "Devs:keymaps/"; 
  49. #define MAXKEYMAPLEN 32
  50.  
  51. static struct KeyMap *findmap(const char *name)
  52. {
  53.   struct KeyMapNode *keymap_n;
  54.   BPTR keySegs;
  55.   char fullKeyMapName[sizeof(keyMapDir) + MAXKEYMAPLEN];
  56.   struct KeyMapResource *keyMapBase =
  57.     (struct KeyMapResource *)OpenResource("keymap.resource");
  58.  
  59.   if (!keyMapBase)
  60.     return NULL;
  61.  
  62.   /* Is it already loaded? */    
  63.   keymap_n = (struct KeyMapNode *)
  64.     FindName(&(keyMapBase->kr_List), (UBYTE *)name);
  65.   if (!keymap_n) {
  66.     /* Not found, we load it from devs:keymaps */
  67.     strcpy(fullKeyMapName, keyMapDir);
  68.     strncat(fullKeyMapName, name, MAXKEYMAPLEN);
  69.     keySegs = LoadSeg(fullKeyMapName);
  70.     if (!keySegs) 
  71.       return NULL;
  72.     keymap_n = (struct KeyMapNode *)((LONG *) (keySegs << 2) + 1);
  73.     AddHead(&(keyMapBase->kr_List), (struct Node *)keymap_n);
  74.   }
  75.   return &(keymap_n->kn_KeyMap);
  76. }
  77.  
  78. /*
  79.  * Use named keymap. If map is non-NULL, use it.
  80.  * Default map is treated as -1
  81.  * Return pointer to new keymap
  82.  *
  83.  * If named keymap can not be found from memory, load it from disk
  84.  */
  85. void *setmap(const char *name, void *map)
  86. {
  87.   if (map) {
  88.     if (map != (void *)-1) {
  89.       used_map = map;
  90.     } else {
  91.       used_map = NULL;
  92.     }
  93.   } else if (name) {
  94.     used_map = findmap(name);
  95.   } else {
  96.     used_map = default_map;
  97.   }
  98.  
  99.   if (used_map) 
  100.     return used_map;
  101.   else
  102.     return (void *)-1;
  103. }
  104.  
  105. /*
  106.  * Initialize keymaps
  107.  */
  108. void initkeys(void)
  109. {
  110.   if(OpenDevice("console.device", -1L, (struct IORequest *)&consolereq, 0L))
  111.     fatalError("Failure to open console.device");
  112.  
  113.   default_map = setmap(np.keymap, NULL);
  114.   if (default_map == (struct KeyMap *)-1)
  115.     default_map = NULL;
  116. }
  117.  
  118. /*
  119.  * Free resources allocated by this module
  120.  */
  121. void deinitkeys(void)
  122. {
  123.   if (ConsoleDevice) 
  124.     CloseDevice((struct IORequest *)&consolereq);
  125.   ConsoleDevice = NULL;
  126. }
  127.  
  128. /*
  129.  * Handle an Intuition RAWKEY message.  
  130.  *
  131.  * The function keys, cursor keys, and keypad may have either the
  132.  * native Amiga values, or the vt100/vt52 values.
  133.  */
  134. #define ISCURSOR(c) (((c)>75) && ((c)<80))
  135. #ifdef OWNICONIFY 
  136. #define ICONIFY(c, q) (((q) & AMIGALEFT) && ((q) & AMIGARIGHT) && ((c) == 23))
  137. #endif
  138.  
  139. static long keyconvert(struct IntuiMessage *msg, char *kbuffer, long kbsize);
  140.  
  141. void dokeys(struct IntuiMessage *msg)
  142. {
  143.   UBYTE buf[512], *convertp = buf + sizeof buf / 2, *endp, *sendp;
  144.   int count;
  145.  
  146.   static const char applkeypad[0x60] = 
  147.     {
  148.       0,   0,   0,   0,   0,   0,   0,   0,
  149.       0,   0,   0,   0,   0,   0,   0, 'p', /* 0 */
  150.       0,   0,   0,   0,   0,   0,   0,   0,
  151.       0,   0,   0,   0,   0, 'q', 'r', 's', /* 1 2 3 */
  152.       0,   0,   0,   0,   0,   0,   0,   0,
  153.       0,   0,   0,   0,   0, 't', 'u', 'v', /* 4 5 6 */
  154.       0,   0,   0,   0,   0,   0,   0,   0,
  155.       0,   0,   0,   0, 'n', 'w', 'x', 'y', /* . 7 8 9 */
  156.       0,   0,   0, 'M',   0,   0,   0,   0, /* Enter */
  157.       0,   0, 'm',   0,   0,   0,   0,   0, /* - */
  158.       0,   0,   0,   0,   0,   0,   0,   0,
  159.       0,   0, 'P', 'Q', 'R', 'S', 'l',   0, /* ( ) / * + */
  160.     };
  161.  
  162.   if (np.applkeypad && msg->Code < 0x60 &&
  163.       applkeypad[(BYTE)(msg->Code)] != 0) {
  164.     /* Application keypad handling */
  165.     convertp[0] = CTRL8('O');
  166.     convertp[1] = applkeypad[(BYTE)(msg->Code)];
  167.     count = 2;
  168.   } else if (ISCURSOR(msg->Code)) {
  169.     /* Cursor keys */
  170.     count = 2;
  171.     convertp[1] = msg->Code - 76 + 'A';
  172.  
  173.     switch (np.cursormap) {
  174.     case CURSOR_VT100:
  175.       convertp[0] = CTRL8('[');    /* CSI */
  176.       break;
  177.     case CURSOR_ANSI:
  178.       convertp[0] = CTRL8('O');
  179.       break;
  180.     case CURSOR_VT52:
  181.       convertp[0] = 033;
  182.       break;
  183.     default:
  184.       count = 0;
  185.     }
  186.   } else {
  187.     count = keyconvert(msg, convertp, sizeof(buf) / 2);
  188.   }
  189.  
  190.  
  191.   /* If alt is treated as meta, we add ESC before a single char */
  192.   if (np.altismeta && (msg->Qualifier & IEQUALIFIER_LALT) && count == 1) {
  193.     buf[0] = ESC;
  194.     sendp = buf + 1;
  195.   } else {
  196.     sendp = buf;
  197.   }
  198.  
  199.   ReplyMsg((struct Message *)msg);
  200.  
  201.   /* Convert keycodes before sending them */
  202.   if (count != 0) {
  203.     for (endp = convertp + count; convertp < endp; ) {
  204.       UBYTE c = *convertp++;
  205.  
  206.       if ((c & 0xe0) == 0x80 && !np.ctrl8bit) {
  207.     /* 8-bit control codes are converted into ESC-sequences */
  208.     *sendp++ = ESC;
  209.     c += '@' - 0x80;
  210.       } else if (c == '\015' && np.ansi_LNM) {
  211.     /* CR is converted into CRLF pair */
  212.     *sendp++ = c;
  213.     c = '\012';
  214.       } else if (np.national == NAT_7BIT) {
  215.     /* Characters are converted into national codes */
  216.     c = national_send[c];
  217.       }
  218.  
  219.       *sendp++ = c;
  220.     }
  221.  
  222.     nwrite(buf, sendp - buf);
  223.   }
  224. }
  225.  
  226. static long keyconvert(struct IntuiMessage *msg, char *kbuffer, long kbsize)
  227. {
  228.   struct InputEvent ievent;
  229.     
  230.   if(msg->Code & IECODE_UP_PREFIX)
  231.     return 0;
  232.  
  233.   ievent.ie_Code = msg->Code;
  234.     
  235.   /* swap BS and DEL */
  236.   if (ievent.ie_Code == 70 && np.delete)
  237.     ievent.ie_Code = 65;
  238.   else if (ievent.ie_Code == 65 && np.backspace)
  239.     ievent.ie_Code = 70;
  240.  
  241.   ievent.ie_NextEvent = 0;
  242.   ievent.ie_SubClass = 0;
  243.   ievent.ie_Class = IECLASS_RAWKEY;
  244.   ievent.ie_Qualifier = msg->Qualifier;
  245.   ievent.ie_position.ie_addr = *((APTR *)msg->IAddress);
  246.   /* This waz a mysterious bug */
  247.   if (np.altismeta) {        /* left alt is meta char */
  248.     ievent.ie_Qualifier &= ~IEQUALIFIER_LALT;
  249.     ievent.ie_position.ie_dead.ie_prev1DownQual &= ~IEQUALIFIER_LALT;
  250.     ievent.ie_position.ie_dead.ie_prev2DownQual &= ~IEQUALIFIER_LALT;
  251.   }
  252.  
  253.   return (RawKeyConvert(&ievent, kbuffer, kbsize, 
  254.             np.national ? used_map : default_map));
  255. }
  256.  
  257.